<template>
  <div id="barrageShowPage">
    <div class="barrage-container">
      <div
        class="mask"
        ref="maskRef"
        :style="{
          backgroundImage: `url('${bgUrl}')`,
          backgroundSize: 'cover',
          backgroundPosition: 'center',
        }"
      >
        <!-- 渲染弹幕组件（核心改造点） -->
        <Danmu
          v-for="(item, index) in danmuList"
          :key="item.id"
          :content="item.content"
          :custom-style="item.style"
          :user="item.user"
        />
      </div>
      <!-- 底部发言框 -->
      <div class="bottom" ref="bottomRef">
        <a-input
          class="content"
          placeholder="说说你的想法吧...."
          v-model:value="inputContent"
          ref="inputRef"
          @pressEnter="sentBarrage"
          size="large"
        />
        <a-button class="send" @click="sentBarrage">发布</a-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { nextTick, onMounted, reactive, ref } from 'vue'
import { Input, message } from 'ant-design-vue'
import { addBarrageUsingPost, listBarrageVoByPageUsingPost } from '@/api/barrageController'
import img1 from '@/assets/barragebackground/Pedestrianfemalelead.jpg'
import img2 from '@/assets/barragebackground/siyue.jpeg'
import img3 from '@/assets/barragebackground/yourname.jpg'
import img4 from '@/assets/barragebackground/yukino4.jpg'
import img5 from '@/assets/barragebackground/Sakura.png'
import img6 from '@/assets/barragebackground/weather.jpg'
import Danmu from '@/components/Danmu.vue'
import { useLoginUserStore } from '@/stores/userLogin'

// --------------- 弹幕生成基本代码 ----------------
// 存储所有弹幕的内容和样式
const danmuList = ref<any[]>([])
// 对外曾 mask 引用对象
const maskRef = ref<HTMLElement | null>(null)
// 获取文本框内的内容
const inputContent = ref<string>('')
// 模板引用输入框
const inputRef = ref<InstanceType<typeof Input> | null>(null)
// 获取底部发言框
const bottomRef = ref<HTMLElement | null>(null)

// ----------- 随机弹幕颜色 ----------------
// 弹幕背景色预设（柔和色调）
// 带透明度的背景色（解决透明度需求）
const bgColors = [
  'rgba(255, 228, 181, 0.9)',
  'rgba(176, 224, 230, 0.9)',
  'rgba(255, 192, 203, 0.9)',
  'rgba(144, 238, 144, 0.9)',
  'rgba(216, 191, 216, 0.9)',
  'rgba(240, 230, 140, 0.9)',
  'rgba(173, 216, 230, 0.9)',
  'rgba(250, 160, 160, 0.9)',
]

// 获取当前登录用户信息
const loginUserStore = useLoginUserStore()
const loginUser = loginUserStore.loginUser

// 动画持续时间（弹幕从右侧滑到左侧的总时长）
// 10秒（与动画transition时间一致）
const animationDuration = 10000

// 将一个 div 添加到 mask 容器中
const sentBarrage = async () => {
  if (!inputContent.value.trim()) {
    message.error('请输入内容')
    // 空内容时也聚焦输入框
    focusInput()
    return
  }

  // 1. 先发送到后端（可选：成功后再渲染）
  const res = await addBarrageUsingPost({ content: inputContent.value })
  if (res.data.code === 0) {
    message.success('发布成功')
  } else {
    message.error('发布失败')
    return
  }

  // 2. 计算弹幕样式（随机背景、位置、动画）
  const [maskHeight, bottomHeight] = await nextTick(() => {
    return [maskRef.value?.offsetHeight || 0, bottomRef.value?.offsetHeight || 0]
  })

  // 生成前端唯一ID（时间戳 + 随机数）
  const uniqueId = Date.now() + Math.random()

  // 计算top时，按“轨道高度”分段，避免弹幕垂直方向重叠
  const trackHeight = 60 // 每条轨道高度（弹幕高度+间距）
  const maxTrack = Math.floor((maskHeight - bottomHeight) / trackHeight) - 1
  const randomTrack = Math.floor(Math.random() * maxTrack)
  const safeTop = randomTrack * trackHeight + 15 // 10px间距

  const randomStyle = {
    top: `${safeTop}px`,
    backgroundColor: bgColors[Math.floor(Math.random() * bgColors.length)],
    transform: `translateX(${window.innerWidth}px)`, // 初始在右侧外部
    opacity: 0.8,
  }

  // 3. 添加到弹幕列表（触发组件渲染）
  danmuList.value.push({
    id: uniqueId,
    content: inputContent.value,
    style: randomStyle,
    user: loginUser,
  })

  // 随机延迟（0~3秒），实现交错效果
  const randomDelay = Math.random() * 1000 // 0-1000毫秒

  // 关键：强制触发动画（用nextTick确保DOM已更新）
  nextTick(() => {
    const danmu = danmuList.value.find((item) => item.id === uniqueId)
    if (danmu) {
      // 先移除过渡，设置初始位置
      danmu.style.transition = 'none'
      danmu.style.transform = `translateX(${window.innerWidth}px)`
      // 随机延迟后启动动画
      setTimeout(() => {
        // 启动动画
        danmu.style.transition = `transform ${animationDuration / 1000}s linear`
        danmu.style.transform = 'translateX(-200%)'

        // 4. 动画开始后，才设置删除定时器（时间=动画持续时间）
        // 定时器：根据ID删除，避免误删重复内容
        setTimeout(() => {
          danmuList.value = danmuList.value.filter((item) => item.id !== uniqueId)
        }, animationDuration)
      }, randomDelay) // 延迟randomDelay后才开始动画
    }
  })

  // 5. 清空输入框
  inputContent.value = ''
  // 用nextTick确保DOM更新后再聚焦
  nextTick(() => {
    focusInput()
  })
}

// 封装聚焦函数（解决焦点失效问题）
const focusInput = () => {
  if (inputRef.value) {
    // Ant Design Vue的Input组件通过$el属性获取原生输入框
    const inputElement = inputRef.value.$el.querySelector('input') as HTMLInputElement
    if (inputElement) {
      inputElement.focus()
      // 强制触发聚焦（针对某些浏览器兼容问题）
      inputElement.scrollIntoView({ block: 'nearest' })
    }
  }
}

// ------------- 从后端获取弹幕 ----------------
const searchParams = reactive<API.BarrageQueryDTO>({
  current: 1,
  pageSize: 30,
  sortField: 'createTime',
  sortOrder: 'descend',
})
// 记录已加载的后端弹幕 ID，避免重复添加
const loadedIds = ref<Set<string>>(new Set())

const fetchBarrage = async () => {
  const res = await listBarrageVoByPageUsingPost({
    ...searchParams,
  })
  if (res.data.code === 0 && res.data.data) {
    // 获取弹幕容器
    const [maskHeight, bottomHeight] = await nextTick(() => [
      maskRef.value?.offsetHeight || 0,
      bottomRef.value?.offsetHeight || 0,
    ])

    // 遍历后端返回的弹幕数据
    ;(res.data.data.records ?? []).forEach((barrage: any) => {
      // 跳过已加载的弹幕
      if (loadedIds.value.has(barrage.id)) {
        return
      }
      // 标记为已加载
      loadedIds.value.add(barrage.id)

      // 计算top时，按“轨道高度”分段，避免弹幕垂直方向重叠
      const trackHeight = 60 // 每条轨道高度（弹幕高度+间距）
      const maxTrack = Math.floor((maskHeight - bottomHeight) / trackHeight) - 1
      const randomTrack = Math.floor(Math.random() * maxTrack)
      const safeTop = randomTrack * trackHeight + 15 // 10px间距

      const randomStyle = {
        top: `${safeTop}px`,
        backgroundColor: bgColors[Math.floor(Math.random() * bgColors.length)],
        transform: `translateX(${window.innerWidth}px)`,
        opacity: 0.8,
      }
      danmuList.value.push({
        id: barrage.id,
        content: barrage.content,
        style: randomStyle,
        user: barrage.user,
      })

      // 后端弹幕同样添加随机延迟
      const randomDelay = Math.random() * 7000

      //  关键：强制触发动画（用nextTick确保DOM已更新）
      nextTick(() => {
        const danmu = danmuList.value.find((item) => item.id === barrage.id)
        if (danmu) {
          danmu.style.transition = 'none'
          danmu.style.transform = `translateX(${window.innerWidth}px)`

          // 随机延迟后启动动画
          setTimeout(() => {
            // 启动动画
            danmu.style.transition = `transform ${animationDuration / 1000}s linear`
            danmu.style.transform = 'translateX(-200%)'

            // 动画开始后设置删除定时器
            setTimeout(() => {
              danmuList.value = danmuList.value.filter((item) => item.id !== barrage.id)
              loadedIds.value.delete(barrage.id)
            }, animationDuration)
          }, randomDelay)
        }
      })
    })
    // 页码递增与重置逻辑
    if (Number(searchParams.current) >= (res.data.data?.pages ?? 0)) {
      // 已到达最后一页，重置为第1页，并清空loadedIds允许重新加载
      searchParams.current = 1
      loadedIds.value.clear() // 清空历史ID，允许重新加载第1页数据
      console.log('已到达最后一页，重置为第1页')
    } else {
      // 未到最后一页，页码 +1
      searchParams.current = (searchParams.current ?? 0) + 1
    }
  }
}
// --------------- 背景图片切换 ----------------
const bgImages = [img1, img2, img3, img4, img5, img6]

// 响应式数据：存储当前背景图的 URL
const bgUrl = ref('')

// 挂载时获取弹幕容器
onMounted(() => {
  // 背景图片默认加载
  // 随机选一张背景图
  const randomIndex = Math.floor(Math.random() * bgImages.length)
  bgUrl.value = bgImages[randomIndex]
  // 页面加载时调用
  fetchBarrage()
  // 每 8 秒轮询一次后端弹幕
  setInterval(fetchBarrage, 8000)
})
</script>

<style scoped>
/* 父容器占满屏幕，作为定位基准 */
#barrageShowPage {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

/* 核心容器：控制四周边距 */
.barrage-container {
  position: relative;
  margin: 20px;
  height: calc(100vh - 40px);
  overflow: hidden;
}

/* 弹幕容器：全屏 + 动态背景 */
.mask {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  overflow: visible;
  z-index: 1; /* 新增：低于弹幕，高于页面背景 */
}

/* 底部交互栏：半透明 + Flex 布局 */
.bottom {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 15px 20px; /* 上下内边距，左右留白 */
  background: rgba(0, 0, 0, 0.1); /* 半透明黑，透出背景图 */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0; /* 消除元素间距 */
  z-index: 10; /* 确保在弹幕之上 */
}

/* 输入框：半透明 + 聚焦动效 */
.content {
  flex: 1; /* 占满剩余空间 */
  max-width: 600px; /* 限制最大宽度 */
  height: 42px;
  padding: 0 18px;
  font-size: 16px;
  color: #fff; /* 白色文字 */
  background: rgba(255, 255, 255, 0.15); /* 更通透的背景 */
  border: 1px solid #666;
  border-right: none; /* 与按钮衔接 */
  border-radius: 22px 0 0 22px; /* 左圆角 */
  outline: none;
  transition: box-shadow 0.3s;
}

.content:focus {
  box-shadow: 0 0 12px rgba(0, 255, 0, 0.4); /* 聚焦时绿色光效 */
}

/* 发送按钮：渐变 + Hover 动效 */
.send {
  width: 120px;
  height: 42px;
  line-height: 42px;
  text-align: center;
  background: linear-gradient(45deg, #4caf50, #8bc34a); /* 绿渐变 */
  color: #fff;
  border: none;
  border-radius: 0 22px 22px 0; /* 右圆角 */
  cursor: pointer;
  transition:
    transform 0.3s,
    background 0.3s;
}

.send:hover {
  transform: scale(1.05); /* 轻微放大 */
  background: linear-gradient(45deg, #8bc34a, #4caf50); /* 渐变反转 */
}

/* 弹幕样式保持不变 */
.barrage-text {
  position: absolute;
  right: 100%;
  top: 0;
  color: white;
  font-size: 20px;
  white-space: nowrap;
}

/* 响应式适配 */
@media (max-width: 768px) {
  .barrage-container {
    margin: 10px;
    height: calc(100vh - 20px);
  }

  .content {
    max-width: 300px;
  }
}
</style>
